<!-- 表单 》 日期 -->

<template>
  <el-form-item v-bind="formItem">
    <!-- 标签 -->
    <template v-if="hasLabelSlot" #label>
      <slot name="label" :label="formItem.label">{{ formItem.label }}</slot>
    </template>

    <el-date-picker v-model="model" v-bind="commonProps" type="date" @change="emitChange" />
  </el-form-item>
</template>

<script>
// ============================== 导入依赖 ============================== //

import CORE from '@/CORE'
import dayjs from 'dayjs'
import mixForm from '../mixForm'

const name = 'FormDate'

// ============================== 导出组件 ============================== //

export default {
  /**
   * 名称定义 (实际使用名称)
   */
  name,

  /**
   * 混入列表 (配置选项合并)
   */
  mixins: [mixForm],

  /**
   * 属性注册 (抽取以便查阅)
   */
  props: CORE.WEB[name],

  /**
   * 计算属性 (慎用箭头函数)
   */
  computed: {
    /**
     * 选择器配置
     */
    pickerOptions() {
      const { weekFirst, disabledDate, noQuick, history, future, quickHistory, quickFuture, quickAll } = this
      const shortcuts = noQuick ? [] : history ? quickHistory : future ? quickFuture : quickAll
      return { firstDayOfWeek: weekFirst, disabledDate, shortcuts }
    },

    /**
     * 公共属性
     */
    commonProps() {
      // FormYear 组件的格式化值 'yyyy' 有可能需要保存为 number 类型
      const { placeholder, className, size, noQuick, format, number, center, pickerOptions } = this
      const centerStr = center ? ` ${className}-center` : ''
      return {
        ...this.elProps,
        name: this.prop,
        class: `${className}${centerStr}`,
        disabled: this.isDisabled,
        clearable: !this.noClear,
        placeholder,
        size,
        popperClass: noQuick ? 'CoreWeb-FormPopper' : 'CoreWeb-FormPopper CoreWeb-FormPopper-quick',
        valueFormat: format || number ? 'yyyy-MM-dd' : 'timestamp',
        pickerOptions,
      }
    },
  },

  /**
   * 本地方法 (轻量重要在前)
   */
  methods: {
    /**
     * 是否不等 (可覆盖)
     */
    isDiff() {
      const { obj, prop, init, EMPTY, number, string, fixValue, lastSecond } = this
      const value = number && CORE.isNumber(obj[prop]) ? `${obj[prop]}` : obj[prop]
      const model = this.model && string ? `${this.model}` : this.model

      // 无值
      if (!value) return model || init || (value !== EMPTY)
      // 不等
      if (value !== fixValue(model, lastSecond)) return true
      // 相等，再判断是否符合格式化数据
      return value === fixValue(value, lastSecond)
    },

    /**
     * 设置内部绑定值 (可覆盖)
     */
    setModel() {
      const { obj, prop, init, EMPTY, number, string, fixValue } = this
      let value = obj[prop]
      if (number && CORE.isInt(value)) value = `${value}`
      if (string && CORE.isInt(value)) value = Number(value)
      this.model = fixValue(value || init || EMPTY, false)
    },

    /**
     * 获取最终回传值 (可覆盖)
     */
    getValue() {
      const { model, EMPTY, format, number, string, fixValue, lastSecond } = this
      if (!model) return EMPTY
      if (number) return +model
      if (format || !string) return fixValue(model, lastSecond)
      return `${fixValue(model, lastSecond)}`
    },

    /**
     * 修复的数据
     */
    fixValue(value, lastSecond) {
      if (!value) return value

      const { $options: { name }, format, number, string, history } = this

      const len = name.includes('Date') ? 10 : name.includes('Month') ? 7 : name.includes('Year') ? 4 : 19

      let str = CORE.timeStr(value).slice(0, len)

      // 选择年份，返回数字的情况
      if (number) return str

      if (lastSecond) { // 是否为最后一秒 (FormTime 无此选项)
        let obj = dayjs(str)
        if (name.includes('Date')) obj = obj.add(1, 'day') // 加一天
        else if (name.includes('Month')) obj = obj.add(1, 'month') // 加一月
        else if (name.includes('Year')) obj = obj.add(1, 'year') // 加一年
        if (history && obj.isAfter(Date.now())) obj = dayjs(CORE.today(1)) // 历史日期，最大是明天
        obj = obj.add(-1, 'second') // 在以上结果的基础上，再减 1 秒
        str = obj.format('YYYY-MM-DD HH:mm:ss')
      }

      return format ? str : string ? `${CORE.timeNum(str)}` : CORE.timeNum(str)
    },

    /**
     * 禁用日期
     */
    disabledDate(date) {
      const { history, future } = this
      if (!date) return false
      if (history) return date.getTime() > dayjs().valueOf()
      if (future) return date.getTime() < dayjs().startOf('day').valueOf()
      return false
    },
  },
}
</script>
